<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>RegExp</title>
</head>
<body>
    <script>
        /* 总结：
            1.创建方式：
                ->创建方式一：/正则表达式/
                ->创建方式二：new RegExp('正则表达式') 注意：字符串的转义问题，字符串的两个\\实际上是一个\
            2.匹配字符串test()
                ->返回值类型为布尔
            3.切分字符串split()
                ->返回值类型为数组
                ->与其相反操作的arr.join()
                ->普通split的缺陷：无法连续匹配空格，正则可以 
            4.分组exec()
                ->在RegExp对象上用exec()方法提取出子串来。
                    -exec()方法在匹配成功后，会返回一个Array，第一个元素是正则表达式匹配到的整个字符串，后面的字符串表示匹配成功的子串。
                    -exec()方法在匹配失败时返回null。
            5.贪婪匹配(JavaScript默认为贪婪匹配)
                ->贪婪匹配，也就是匹配尽可能多的字符。
                ->非贪婪匹配（也就是尽可能少匹配）
            6.全局搜索
                ->JavaScript的正则表达式还有几个特殊的标志，最常用的是g，表示全局匹配
                ->创建方式：var r1 = /test/g 或 var r2 = new RegExp('test', 'g'); 可以有多个标志
                ->全局匹配可以多次执行exec()方法来搜索一个匹配的字符串。当我们指定g标志后，每次运行exec()，正则表达式->身会更新lastIndex属性，表示上次匹配到的最后索引
                ->全局匹配类似搜索，因此不能使用/^...$/，那样只会最多匹配一次。
                ->正则表达式还可以指定i标志，表示忽略大小写，m标志，表示执行多行匹配。
            7.正则匹配规则（略）
         */
        "use strict";
        //1.创建方式一：/正则表达式/
        var re1 = /ABC\-001/;
        console.log(re1);// /ABC\-001/
        //2.创建方式二：new RegExp('正则表达式')
        //注意：因为字符串的转义问题，字符串的两个\\实际上是一个\
        var re1 = new RegExp("ABC\\-001");
        console.log(re1);// /ABC\-001/s

        //3.匹配字符串test()
        console.log("test:");
        var re1 = /^\d{3}\-\d{3,8}/g;
        re1 = new RegExp("^\\d{3}\\-\\d{3,8}$",'g');
        console.log(re1);// /^\d{3}\-\d{3,8}$/
        console.log(re1.test("032-1234"));//true
        console.log(re1.test("023-12345678x"));//false
        //全局匹配
        var re1 = /\d{3}/g;
        var str = "0311234031";
        console.log(re1.test(str));//true
        console.log(re1.lastIndex);//3
        console.log(re1.test(str));//true
        console.log(re1.lastIndex);//6

        //4.切分字符串 split
        //join与split 相反的操作
        var arr = [1,2,3,4];
        var str = arr.join('-');
        console.log(str);
        var arr1 = str.split('-');
        console.log(arr1);

        //split的正则应用
        /*
            1.普通split的缺陷：无法连续匹配空格，正则可以 
         */
        var str = "a b   c";
        console.log(str.split(' '));//["a", "b", "", "", "c"]
        console.log(str.split(/\s+/));//["a", "b", "c"]
        var str = "a b,  c";
        console.log(str.split(/[\s,]+/));//["a", "b", "c"]
        var str = "a b,; ; c";
        console.log(str.split(/[\s,;]+/));//["a", "b", "c"]

        //5.分组 exec
        /* 
            1.在RegExp对象上用exec()方法提取出子串来。
                -exec()方法在匹配成功后，会返回一个Array，第一个元素是正则表达式匹配到的整个字符串，后面的字符串表示匹配成功的子串。
                -exec()方法在匹配失败时返回null。
            2.
         */
        var re = /^(\d{3})-(\d{3,8})$/;
        //["010-12345", "010", "12345", index: 0, input: "010-12345", groups: undefined]
        console.log(re.exec('010-12345'));
        console.log(re.exec('010 12345'));// null
        //匹配时间
        var re = /^(0[0-9]|1[0-9]|2[0-3]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])$/
        // ["9:05:30", "9", "05", "30", index: 0, input: "9:05:30", groups: undefined]
        console.log(re.exec('9:05:30'));
        //匹配日期
        //这里的4-31,2-30属于非法日期，但仍会匹配上
        var re = /^(0[1-9]|1[0-2]|[0-9])-(0[1-9]|1[0-9]|2[0-9]|3[0-1]|[0-9])$/;
        console.log(re.exec("4-31"));//["4-31", "4", "31", index: 0, input: "4-31", groups: undefined]
        console.log(re.exec("2-30"));

        //6.贪婪匹配（JavaScript默认为贪婪匹配）
        //贪婪匹配，也就是匹配尽可能多的字符。
        var re = /^(\d+)(0*)$/;
        // 由于\d+采用贪婪匹配，直接把后面的0全部匹配了，结果0*只能匹配空字符串了。
        console.log(re.exec('102300'));// ['102300', '102300', '']
        //采用非贪婪匹配（也就是尽可能少匹配）
        var re = /^(\d+?)(0*)$/;
        console.log(re.exec('102300'));//["102300", "1023", "00"]

        //7.全局搜索
        /* 
            1.JavaScript的正则表达式还有几个特殊的标志，最常用的是g，表示全局匹配
            2.创建方式：var r1 = /test/g 或 var r2 = new RegExp('test', 'g');
            3.全局匹配可以多次执行exec()方法来搜索一个匹配的字符串。当我们指定g标志后，每次运行exec()，正则表达式本身会更新lastIndex属性，表示上次匹配到的最后索引
            4.全局匹配类似搜索，因此不能使用/^...$/，那样只会最多匹配一次。
            5.正则表达式还可以指定i标志，表示忽略大小写，m标志，表示执行多行匹配。
         */
         console.log("全局搜索：");
        var s = 'JavaScript, VBScript, JScript and ECMAScript';
        var re=/[a-z]+Script/gi;//多标志
        var re=/[a-zA-Z]+Script/g;
        // 使用全局匹配:正则表达式还可以指定i标志，表示忽略大小写，m标志，表示执行多行匹配。
        console.log(re.exec(s)); // ['JavaScript']
        console.log(re.lastIndex);// 10
        console.log(re.exec(s));// ['VBScript']
        console.log(re.lastIndex);// 20
        console.log(re.exec(s));// ['JScript']
        console.log(re.lastIndex);// 29
        console.log(re.exec(s));// ['ECMAScript']
        console.log(re.lastIndex);// 44
        console.log(re.exec(s));// null，直到结束仍没有匹配到
       
    </script>
</body>
</html>